﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Red.GameData.Raw
{
    public partial class DataProperty
    {
        /// <summary>
        /// XML shitty loading - load the data property from the XML
        /// </summary>
        /// <param name="obj">Parent data object this property belongs to</param>
        /// <param name="log">Error logging interface</param>
        /// <param name="xml">XML node</param>
        /// <returns>Loaded property (or null if there were errors)</returns>
        public static DataProperty LoadFromNode(DataObject obj, IGenericFileErrorReporter log, XmlNode xml)
        {
            // get name of the data property
            // this is a required attribute
            var name = Raw.Utils.Attr(xml, "name");
            if (name == "")
            {
                log.Error(String.Format("Missing name for property in object {0}", Utils.FormatGuid(obj.ID)));
                return null;
            }

            // load additional attributes
            Boolean clearAllIncomingValues = Raw.Utils.Attr(xml, "clearIncomingValues", false); // defaults to false
            Boolean isFinal = Raw.Utils.Attr(xml, "final", false); // defaults to false

            // create the data holder
            var ret = new DataProperty(obj, name, isFinal, clearAllIncomingValues);

            // load sub-objects (mostly values and suppressed value list)
            foreach (var item in xml.ChildNodes)
            {
                var xmlNode = item as XmlNode;
                if (xmlNode != null)
                {
                    if (xmlNode.Name == "value")
                    {
                        var val = DataValue.LoadFromNode(ret, log, xmlNode);
                        if (val != null)
                        {
                            ret.Values.Add(val);
                        }
                    }
                    else if (xmlNode.Name == "suppress")
                    {
                        var suppressId = Raw.Utils.AttrID(xmlNode, "id");
                        if (suppressId != Guid.Empty)
                        {
                            ret.SupressedValues.Add(suppressId);
                        }
                    }
                }
            }

            return ret;
        }

        /// <summary>
        /// XML shitty saving
        /// </summary>
        /// <param name="xml">Target XML node</param>
        public void SaveToNode(XmlElement xml)
        {
            // name is required attribute
            xml.SetAttribute("name", Name);

            // "final" is optional attribute, write it only if it's true (to save XML space)
            if (_isFinal)
                xml.SetAttribute("final", "1");

            // "clearIncomingValues" is also optional, the same as for final - write it only if it's true (to save XML space)
            if (_clearAllIncomingValues)
                xml.SetAttribute("clearIncomingValues", "1");

            // write the list of suppressed values
            foreach (var suppressed in SupressedValues)
            {
                var childXml = xml.OwnerDocument.CreateElement("suppress");
                childXml.SetAttribute("id", Raw.Utils.FormatGuid(suppressed));
                xml.AppendChild(childXml);
            }

            // write the values themselves
            foreach (var val in Values)
            {
                var childXml = xml.OwnerDocument.CreateElement("value");
                val.SaveToNode(childXml);
                xml.AppendChild(childXml);
            }
        }

    }
}
